///
#[cfg(target_os = "linux")]
type EpollEvent = libc::epoll_event;
#[cfg(not(target_os = "linux"))]
pub struct EpollEvent
{
    pub events: u32,
    pub u64: u64,
}

/// 功能：创建一个多路复用的实例
///
/// 参数：
/// flags：
/// 0:如果这个参数是0，这个函数等价于poll_create（0）
/// EPOLL_CLOEXEC：这是这个参数唯一的有效值，如果这个参数设置为这个。那么当进程替换映像的时候会关闭这个文件描述符，这样新的映像中就无法对这个文件描述符操作，适用于多进程编程+映像替换的环境里
///
/// 返回值：
/// success：返回一个非0 的未使用过的最小的文件描述符
/// error：-1 errno被设置
pub fn epoll_create(flags: i32) -> i32
{
    #[cfg(target_os = "linux")]
    unsafe { libc::epoll_create1(flags) }
    #[cfg(not(target_os = "linux"))]
    -1
}

/// 功能：操作一个多路复用的文件描述符
///
/// 参数：
/// epfd：epoll_create1的返回值
/// op：要执行的命令
/// EPOLL_CTL_ADD：向多路复用实例加入一个连接socket的文件描述符
/// EPOLL_CTL_MOD：改变多路复用实例中的一个socket的文件描述符的触发事件
/// EPOLL_CTL_DEL：移除多路复用实例中的一个socket的文件描述符
/// fd：要操作的socket的文件描述符
pub fn epoll_ctl(epfd: i32, op: i32, fd: i32, event: *mut EpollEvent) -> i32
{
    #[cfg(target_os = "linux")]
    unsafe { libc::epoll_ctl(epfd, op, fd, event) }
    #[cfg(not(target_os = "linux"))]
    -1
}

/// 功能：等待一个epoll队列中的文件描述符的I/O事件发生
///
/// 参数：
/// epfd：目标epoll队列的描述符
/// events：用于放置epoll队列中准备就绪（被触发）的事件
/// maxevents：最大事件？
/// timeout：指定函数等待的时间。这个函数阻塞这么长一段时间之后接触阻塞。
///
/// 返回值：
/// >=0，表示准备就绪的文件描述符个数
/// -1：出错，errno被设置
pub fn epoll_wait(epfd: i32, events: *mut EpollEvent, maxevents: i32, timeout: i32) -> i32
{
    #[cfg(target_os = "linux")]
    unsafe { libc::epoll_wait(epfd, events, maxevents, timeout) }
    #[cfg(not(target_os = "linux"))]
    -1
}
